<?php
class Workflow_Service_UserTask
{
	protected $db;
	
	public function __construct($db)
	{
		$this->db = $db;
	}
	
	public function getCandidateUsers(Workflow_Node_UserTask $node)
	{
		$nodeConfig = $node->getConfiguration();
		
		$class = new ReflectionClass( $nodeConfig['UserRetriever'] );
    	if ( !$class->implementsInterface( 'Workflow_Service_UserRetriever' ) )
        {
        	throw new Exception("UserTask's TaskUser must implent Workflow_Service_UserRetriever");
        }
        
    	$userRetriever = null;
    	
     	if ( !empty( $nodeConfig['UserRetrieverArgs'] ) )
        {
            $userRetriever = $class->newInstanceArgs( $nodeConfig['UserRetrieverArgs'] );
        }
        else
        {
            $userRetriever = $class->newInstance();
        }
        
        return $userRetriever->getUsers();
	}
	
	public function isTaskCompleted($workflowid, $executionid, $nodeId)
	{
			$result = $this->db->fetchRow("SELECT count(0) as count
			from execution_usertask
			where iscompleted = 1
			and workflow_id = ?
			and execution_id = ?
			and usertasknode_id = ?", array($workflowid, $executionid, $nodeId));
    	
    	return (int)$result['count'] == 1;
	}
	
	public function setTaskCompleted($workflowid, $executionid, $nodeId)
	{
		$principal = new Ext_Service_Principal();
    	$identity = $principal->getIdentity();
    	$userid = $identity->id;
    	
    	$where['workflow_id = ?'] = $workflowid;
		$where['execution_id = ?']  = $executionid;
		$where['usertasknode_id = ?']  = $nodeId;
		
		$this->db->update('execution_usertask', array(
    		'iswaiting' => 0,
    		'iscompleted' => 1,
			'assignee' => $userid
    	), $where);
	}
	
	public function setTaskAssignee($workflowid, $executionid, $nodeId)
	{
		$principal = new Ext_Service_Principal();
    	$identity = $principal->getIdentity();
    	$userid = $identity->id;
    	
		$this->db->update('execution_usertask', array(
			'assignee' => $userid
		), array(
			'workflow_id = ?' => $workflowid,
    		'execution_id = ?' => $executionid,
    		'usertasknode_id = ?' => $nodeId
		));
		
		$this->db->delete('execution_workitem_candidates', array(
			'workflow_id = ?' => $workflowid,
    		'execution_id = ?' => $executionid,
    		'usertasknode_id = ?' => $nodeId
		));
	}
	
	public function addWaitingTask($workflowid, $executionid, $nodeId)
	{
		$principal = new Ext_Service_Principal();
    	$identity = $principal->getIdentity();
    	$userid = $identity->id;
    		
		$this->db->insert('execution_usertask', array(
    		'workflow_id' => $workflowid,
    		'execution_id' => $executionid,
    		'usertasknode_id' => $nodeId,
    		'iswaiting' => 1,
    		'iscompleted' => 0,
			'submit_user' => $userid,
			'submit_time' => time()  		
    	));	
	}
	
	public function setWorkItemCandidates($workflowid, $executionid, Workflow_Node_UserTask $node)
	{
		$candidates = $this->getCandidateUsers($node);
		
		foreach ($candidates as $userid)
		{
			$this->db->insert('execution_workitem_candidates', array(
			'workflow_id' => $workflowid,
			'execution_id' => $executionid,
			'usertasknode_id' => $node->getId(),
			'user_id' => $userid
			));
		}		
	}
	
	public function getUserWorkItem($userId)
	{
		$result = $this->db->fetchAll("SELECT u.execution_id, u.usertasknode_id, u.workflow_id, u.submit_user, u.submit_time, n.node_name
				from execution_usertask u,execution_workitem_candidates w, node n
				where u.usertasknode_id = n.node_id and ((u.iscompleted = 0 and u.assignee = ?)
				OR 
				(w.execution_id = u.execution_id
				and w.workflow_id = u.workflow_id
				and w.usertasknode_id = u.usertasknode_id
				and u.assignee is NULL and u.iscompleted = 0
				and w.user_id = ?))", array($userId, $userId));
    	return $result;
	}
}
?>